using UnityEngine;
using UnityEditor; 
using System.Collections;
using System.Collections.Generic;


[CustomEditor(typeof(PositionByCurveOnUpdate))]  
public class PositionByCurveInspector : Editor
{
    public Character character;
    public CharacterAnimatedState state;
    
    PositionByCurveOnUpdate action;
    
    bool drawCurveForward;
    bool drawCurveUp;
    bool drawCurveRight;
    
    Vector3 offset;
    
    void FindReferences()
    {
        state = action.transform.parent.parent.GetComponent<CharacterAnimatedState>();
        character = state.transform.parent.parent.GetComponent<Character>();
    }
    
    public void OnDestory()
    {
        CustomAnimationSampler.SampleMovement(Vector3.zero);
    }
    
    private EditorWindow cachedCurveWindow;
    public override void OnInspectorGUI () 
    {  
        action = target as PositionByCurveOnUpdate;
        
        offset = new Vector3(action.movementRight.Evaluate((float)CustomAnimationSampler.currentFrame),
                             action.movementUp.Evaluate((float)CustomAnimationSampler.currentFrame),
                             action.movementForward.Evaluate((float)CustomAnimationSampler.currentFrame));
        CustomAnimationSampler.SampleMovement(offset);
        
        DrawDefaultInspector();
        
        if(character == null)
        {
            FindReferences();
        }
        
        if(GUILayout.Button("SaveAll"))
        {
            SaveAllCurves(action);
        }
        if(GUILayout.Button("LoadAll"))
        {
            LoadAllCurves(action);
        }
        
        drawCurveForward = EditorGUILayout.Foldout(drawCurveForward, "Forward Curve Key Value");
        if(drawCurveForward)
        {
            action.movementForward = EditorGUILayout.CurveField("Movement Forward", action.movementForward);
            DrawCurveKeyValue(action.movementForward);
            if(GUILayout.Button("Save"))
            {
                SaveOneCurve("movementForward",action.movementForward,action);
            }
            if(GUILayout.Button("Load"))
            {
                LoadOneCurve("movementForward",action.movementForward,action);
            }
        }
        
        drawCurveUp = EditorGUILayout.Foldout(drawCurveUp, "Up Curve Key Value");
        if(drawCurveUp)
        {
            action.movementUp = EditorGUILayout.CurveField("Movement Up", action.movementUp);
            DrawCurveKeyValue(action.movementUp);
            if(GUILayout.Button("Save"))
            {
                SaveOneCurve("movementForward",action.movementUp,action);
            }
            if(GUILayout.Button("Load"))
            {
                LoadOneCurve("movementForward",action.movementUp,action);
            }
        }
        
        drawCurveRight = EditorGUILayout.Foldout(drawCurveRight, "Right Curve Key Value");
        if(drawCurveRight)
        {
            action.movementRight = EditorGUILayout.CurveField("Movement Right", action.movementRight);
            DrawCurveKeyValue(action.movementRight);
            if(GUILayout.Button("Save"))
            {
                SaveOneCurve("movementForward",action.movementRight,action);
            }
            if(GUILayout.Button("Load"))
            {
                LoadOneCurve("movementForward",action.movementRight,action);
            }
        }
        
        if(EditorWindow.focusedWindow != null)
        {
            if(EditorWindow.focusedWindow.ToString().Contains("CurveEditor"))
            {
                if(cachedCurveWindow == null)
                {
                    cachedCurveWindow = (EditorWindow)Object.Instantiate(EditorWindow.focusedWindow);
                }
            }
        }
        if(cachedCurveWindow != null)
        {
            cachedCurveWindow.Show();
            cachedCurveWindow.Focus();
        }
        
    }
    
    void DrawCurveKeyValue(AnimationCurve curve)
    {
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Frame", GUILayout.MaxWidth(100));
        EditorGUILayout.LabelField("Value", GUILayout.MaxWidth(100));
        EditorGUILayout.EndHorizontal();
        int toRemove = -1;
        Keyframe[] keys = curve.keys;
        for(int i = 0; i < keys.Length; i++)
        {
            Keyframe kf = keys[i];
            EditorGUILayout.BeginHorizontal();
            float time = EditorGUILayout.FloatField(kf.time, GUILayout.MaxWidth(100));
            float value = EditorGUILayout.FloatField(kf.value, GUILayout.MaxWidth(100));
            bool remove = GUILayout.Button("Rmv", GUILayout.MaxWidth(50));
            EditorGUILayout.EndHorizontal();
            
            if(remove)
            {
                toRemove = i;
            }
            else if(time != kf.time || value != kf.value) 
            {
                kf.time = time;
                kf.value = value;
                curve.MoveKey(i, kf);
            }
        }
        
        bool addKeyFrame = GUILayout.Button("Add Key Frame", GUILayout.MaxWidth(250));
        
        
        if(toRemove >= 0)
        {
            curve.RemoveKey(toRemove);
        }
        else if(addKeyFrame)
        {
            if(curve.keys.Length > 0 )
            {
                Keyframe last = curve.keys[curve.length - 1];
                curve.AddKey(new Keyframe(last.time + 1, last.value));
            }
            else
            {
                curve.AddKey(new Keyframe(0, 0));
            }
        }
    }
    
    public void SaveAllCurves(PositionByCurveOnUpdate curveAction)
    {
        SaveOneCurve("movementForward",curveAction.movementForward,curveAction);
        SaveOneCurve("movementRight",curveAction.movementRight,curveAction);
        SaveOneCurve("movementUp",curveAction.movementUp,curveAction);
    }
    
    public void SaveOneCurve(string curveName,AnimationCurve curve,CharacterAction action)
    {
        string characterName = "";
        characterName = character.gameObject.name;
        string stateName = state.gameObject.name;
        string path = "Assets/CharacterData/" + characterName + "/" + stateName + "/" + action.name + "/" ;
        Debug.LogError(path);
        AnimationClip clip = new AnimationClip();
        if(!System.IO.Directory.Exists(path))
        {
            Debug.LogError("aa");
            System.IO.Directory.CreateDirectory(path);
        }
        
        if(!System.IO.File.Exists(path + curveName + ".anim"))
        {
            AssetDatabase.CreateAsset (clip, path + curveName + ".anim");
        }
        else
        {
            Debug.LogError("bb");
            clip = (AnimationClip)AssetDatabase.LoadAssetAtPath(path + curveName + ".anim",typeof(AnimationClip));
            Debug.LogError("clip = "+ clip);
        }
        
        clip.SetCurve("", typeof(Transform), "localPosition.x", curve);
        
        AssetDatabase.SaveAssets();
    }
    
    public void LoadAllCurves(PositionByCurveOnUpdate curveAction)
    {
        LoadOneCurve("movementForward",curveAction.movementForward,curveAction);
        LoadOneCurve("movementRight",curveAction.movementRight,curveAction);
        LoadOneCurve("movementUp",curveAction.movementUp,curveAction);
    }
    
    public void LoadOneCurve(string curveName,AnimationCurve curve,PositionByCurveOnUpdate action)
    {
        string characterName = character.gameObject.name;
        string stateName = state.gameObject.name;
        string path = "Assets/CharacterData/" + characterName + "/" + stateName + "/" + action.name + "/";
        Debug.LogError(path);
        AnimationClip clip = (AnimationClip)AssetDatabase.LoadAssetAtPath(path + curveName + ".anim",typeof(AnimationClip));
        if(clip != null)
        {
            AnimationClipCurveData[] data = AnimationUtility.GetAllCurves(clip);
            if(curveName == "movementForward")
            {
                action.movementForward = data[0].curve;
            }
            if(curveName == "movementRight")
            {
                action.movementRight = data[0].curve;
            }
            if(curveName == "movementUp")
            {
                action.movementUp = data[0].curve;
            }
            
            Repaint();
            
        }
        else
        {
            EditorUtility.DisplayDialog("Error","no data saved, please save first","ok");
        }
        
    }
}


